/**
 * PMovimento.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package persistencia.movimento;

import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import negocio.movimento.DivisaoLucro;
import plagio.postgres.ConnectionPostgres;
import negocio.movimento.Movimento;
import negocio.pessoas.Empreendimento;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class PMovimento {

    //<editor-fold defaultstate="collapsed" desc="Attributes">
    private boolean error = false;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acessores">
    public boolean isError(){
        return this.error;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Table Columns">
    static final private String K_TBL_Movimento      = "Movimento";
    static final private String K_COL_cod_objeto     = "cod_objeto";
    static final private String K_COL_empreendimento = "empreendimento";
    static final private String K_COL_tipoMovimento  = "tipomovimento";
    static final private String K_COL_dataMovimento  = "datamovimento";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por realizar a persistencia
     * de um movimento
     * @throws java.io.IOException
     */
    public PMovimento() throws IOException{
        error = false;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Methods">
    /**
     * Responsavel por criar a estrutura para inserir o objeto
     * @return construtor do objeto a ser inserido
     */
    private String formInsert(){
        return "INSERT INTO \"" + K_TBL_Movimento + "\"(" + K_COL_cod_objeto +
               ", " + K_COL_empreendimento + ", " + K_COL_tipoMovimento + ", " +
               K_COL_dataMovimento + ") VALUES (?, ?, ?, ?)";
    }

    /**
     * Responsavel por gerar um movimento para um empreendimento
     * @param obj objeto a ser inserido na base de dados
     * @param emp empreendimento a ser atualizado
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean gerarMovimento(Movimento obj, Empreendimento emp,
                                                ArrayList<DivisaoLucro> lstDv){
        Boolean status = true;
        ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

        try{
            // Realiza a conexao com o servidor
            java.util.Date data = new java.util.Date();
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Monta o objeto em uma instrucao SQL para insercao no banco
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);
            stat.setString(1, obj.getCod_objeto());
            stat.setString(2, obj.getEmpreendimento());
            stat.setInt(3, obj.getTipoMovimento());
            stat.setDate(4, new java.sql.Date(data.getTime()));
            stat.executeUpdate();

            // Atualiza todos os empreendimentos para finalizados
            query = "UPDATE \"Empreendimento\" SET status = ?, dtvenda"+
                    " = ?, valorVenda = ? WHERE cod_objeto = ?";
            stat = conn.getConnection().prepareStatement(query);
            stat.setInt(1, emp.getStatus());
            stat.setDate(2,emp.getDtVenda() == null ? null :
                     new java.sql.Date(emp.getDtVenda().getTime()));
            stat.setDouble(3, emp.getValorVenda());
            stat.setString(4, emp.getCod_objeto());
            stat.executeUpdate();

            // Realiza a divisao de lucros
            query = new PDivisaoLucro().formInsert();
            stat = conn.getConnection().prepareStatement(query);
            for(DivisaoLucro dv : lstDv){
                stat.setString(1, dv.getCod_objeto());
                stat.setString(2, dv.getInvestidor());
                stat.setString(3, dv.getEmpreendimento());
                stat.setDouble(4, dv.getValorRecebido());
                stat.executeUpdate();
            }
            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        finally{
            conn.closeConnection();
        }
        return status;
    }

    /**
     * Gera uma lista de movimentos
     * @param lstEmp lista de empreendimentos que tera seu estado mudado
     * @param lstMov lista de movimentos que serao gerados
     * @return TRUE se verdadeiro FALSE caso contrario
     */
    public Boolean gerarMovimento(ArrayList<Empreendimento> lstEmp,
                                  ArrayList<Movimento> lstMov){
        Boolean status = true;
        ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

        try{
            java.util.Date data = new java.util.Date();

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Monta o objeto em uma instrucao SQL para insercao no banco
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);

            // Insere todos os movimentos recebidos
            for(Movimento mov : lstMov){
                stat.setString(1, mov.getCod_objeto());
                stat.setString(2, mov.getEmpreendimento());
                stat.setInt(3, mov.getTipoMovimento());
                stat.setDate(4, new java.sql.Date(data.getTime()));
                stat.executeUpdate();
            }

            // Atualiza todos os empreendimentos para finalizados
            query = "UPDATE \"Empreendimento\" SET status = ?, datatermefetivo"+
                    " = ? WHERE cod_objeto = ?";
            for(Empreendimento emp : lstEmp){
                stat = conn.getConnection().prepareStatement(query);
                stat.setInt(1, emp.getStatus());
                stat.setDate(2,emp.getDataTermEfetivo() == null ? null :
                         new java.sql.Date(emp.getDataTermEfetivo().getTime()));
                stat.setString(3, emp.getCod_objeto());
                stat.executeUpdate();
            }

            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        finally{
            conn.closeConnection();
        }
        return status;
    }

    /**
     * Gera uma lista de movimentos de estorno de vendas
     * @param lstEmp lista de empreendimentos que tera seu estado mudado
     * @param lstMov lista de movimentos que serao gerados
     * @return TRUE se verdadeiro FALSE caso contrario
     */
    public Boolean gerarMovimentoEstVenda(ArrayList<Empreendimento> lstEmp,
                                  ArrayList<Movimento> lstMov){
        Boolean status = true;
        ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

        try{
            java.util.Date data = new java.util.Date();

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            conn.getConnection().setAutoCommit(false);

            // Monta o objeto em uma instrucao SQL para insercao no banco
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);

            // Insere todos os movimentos recebidos
            for(Movimento mov : lstMov){
                stat.setString(1, mov.getCod_objeto());
                stat.setString(2, mov.getEmpreendimento());
                stat.setInt(3, mov.getTipoMovimento());
                stat.setDate(4, new java.sql.Date(data.getTime()));
                stat.executeUpdate();
            }

            for(Empreendimento emp : lstEmp){
                // Atualiza todos os empreendimentos para finalizados
                query = "UPDATE \"Empreendimento\" SET status = ?, dtvenda = ?, "+
                        "valorvenda = ? WHERE cod_objeto = ?";

                stat = conn.getConnection().prepareStatement(query);
                stat.setInt(1, emp.getStatus());
                stat.setDate(2,emp.getDataTermEfetivo() == null ? null :
                         new java.sql.Date(emp.getDataTermEfetivo().getTime()));
                stat.setDouble(3, 0.00);
                stat.setString(4, emp.getCod_objeto());
                stat.executeUpdate();

                // Recupera a lista de divisao para um dado empreendimento
                ArrayList<DivisaoLucro> lstDv = new ArrayList<DivisaoLucro>();
                lstDv = new DivisaoLucro().recLstDivEmp(emp.getCod_objeto());

                for(DivisaoLucro dl : lstDv){
                    query = new PDivisaoLucro().formDelete(dl);
                    stat = conn.getConnection().prepareStatement(query);
                    stat.executeUpdate();
                }
            }

            stat.close();
            conn.getConnection().commit();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        finally{
            conn.closeConnection();
        }
        return status;
    }
    //</editor-fold>
}